(function($) {
    var arkflow = $.arkflow;

    // arkflow对象初始化
    // domObj:页面元素 <div id='arkflow'></div>
    // config:arkflow配置对象
    arkflow.ArkFlow = Base.extend({
        constructor:function(domObj, config) {
            console.log('init flow designer');

            this.domObj = domObj;
            this.flowId = config.flowId;

            arkflow.ArkFlow.register(this.flowId, this);

            this.config = config;
            $.extend(true, arkflow.config, config);

            this.initPaper();

            this.initEmptyClick();
            this.bindDelete();
            //当前图形中矩形对象集合
            this.rectArray = {};
            this.pathArray = {};

            this.bindAddNode();
            this.bindAddPath();
            this.bindRemoveNode();

            //工具栏添加拖动、鼠标经过等事件、CSS
            $(this.paper).data("mod", "point");


            this.loadNodes();

            this.loadHistoryAndActiveNodes();

        },
        setMod: function(mod) {
            $(this.paper).data("mod", mod);
        },
        setPointerMod: function() {
            $(this.paper).data("mod", "pointer");
        },
        setPathMod: function() {
            $(this.paper).data("mod", "path");
        },
        addFlowNode: function(type, x, y) {
            $(this.paper).trigger("addrect", [type, {
                attr : {
                    x : x,
                    y : y
                }
            }]);
        },
        initPaper: function() {
            var width = $(window).width();
            var height = $(window).height();
            //Raphael画图对象
            this.paper  = Raphael(this.domObj, width * 1.5,height * 1.5);
        },
        bindDelete: function() {
            var paper = this.paper;
            $(document).keydown(function(event) {
                if (!arkflow.config.editable) {
                    return;
                }
                if (event.keyCode == 46) {//删除元素
                    var currNode = $(paper).data("currNode");
                    if (currNode) {
                        if (currNode.getId().substring(0, 12) == "workflowNode") {
                            $(paper).trigger("removerect", currNode);//删除当前矩形
                        } else {
                            if (currNode.getId().substring(0, 4) == "path") {
                                $(paper).trigger("removepath", currNode);//删除当前路径
                            }
                        }
                        $(paper).removeData("currNode");
                    }
                }
            });
        },
        initEmptyClick: function() {
            var paper = this.paper;
            //元素点击
            $(document).click(function() {
                $(paper).data("currNode", null);
                $(paper).trigger("click", {
                    getId : function() {
                        return "00000000";
                    }
                });
                $(paper).trigger("showprops", [arkflow.config.props.props, {
                    getId : function() {
                        return "00000000";
                    }
                }]);
            });
        },
        bindRemoveNode:function() {
            var me = this;
            //移除元素方法
            var removeNode = function(event, currNode) {
                if (!arkflow.config.editable) {
                    return;
                }
                if (currNode.getId().substring(0, 12) == "workflowNode") {//
                    me.rectArray[currNode.getId()] = null;//置空当前矩形对象集合
                    currNode.remove();//移除对象
                } else if (currNode.getId().substring(0, 4) == "path") {//路径
                    me.pathArray[currNode.getId()] = null;//置空当前路径对象集合
                    currNode.remove();//移除对象
                }
            };
            //绑定移除事件
            $(this.paper).bind("removepath", removeNode);
            $(this.paper).bind("removerect", removeNode);
        },
        bindAddNode: function() {
            var me = this;
            //绑定添加矩形事件
            //type:矩形类型，如task，start，end等，attr:x、y坐标
            $(this.paper).bind("addrect", function(currNode, type, attr) {
                //创建矩形对象
                var rect = new arkflow.FlowNode($.extend(true, {}, arkflow.config.tools.states[type], attr), me.paper);
                //将矩形对象放入集合中
                me.rectArray[rect.getId()] = rect;
            });
        },
        bindAddPath: function() {
            var me = this;
            //添加路径
            var addPath = function(event, node, currNode) {
                //创建路径对象
                var path = new arkflow.Path({}, me.paper, node, currNode);
                //将路径对象放入集合中
                me.pathArray[path.getId()] = path;
            };
            //绑定添加路径事件
            $(this.paper).bind("addpath", addPath);
        },


        toDefineJson: function() {
            var rectArray = this.rectArray;
            var pathArray = this.pathArray;

            var jsonStr = "{states:{";
            for (var rect in rectArray) {
                if (rectArray[rect]) {
                    jsonStr += rectArray[rect].getId() + ":" + rectArray[rect].toJson() + ",";
                }
            }
            if (jsonStr.substring(jsonStr.length - 1, jsonStr.length) == ",") {
                jsonStr = jsonStr.substring(0, jsonStr.length - 1);
            }
            jsonStr += "},paths:{";
            for (var path in pathArray) {
                if (pathArray[path]) {
                    jsonStr += pathArray[path].getId() + ":" + pathArray[path].toJson() + ",";
                }
            }
            if (jsonStr.substring(jsonStr.length - 1, jsonStr.length) == ",") {
                jsonStr = jsonStr.substring(0, jsonStr.length - 1);
            }
            jsonStr += "},props:{props:{";
            for (var path in arkflow.config.props.props) {
                jsonStr += path + ":{value:'" + arkflow.config.props.props[path].value
                    + "'},";
            }
            if (jsonStr.substring(jsonStr.length - 1, jsonStr.length) == ",") {
                jsonStr = jsonStr.substring(0, jsonStr.length - 1);
            }
            jsonStr += "}}}";
            return jsonStr;
        },
        validateDefine: function(defineJson) {
            var result = {
                success: true,
                msg: ''
            };
            var json = defineJson;
            var obj = eval("(" + defineJson + ")");
            var statesCount = 0;
            var pathCount = 0;
            $.each(obj.states, function(idx, item) {
                statesCount++;
            });
            $.each(obj.paths, function(idx, item) {
                pathCount++;
            });
            if (statesCount > pathCount + 1) {
                result.success = false;
                result.msg = "请正常设置流程！";
                return result;
            }
            var num = json.indexOf("type:'start'");
            var endNum = json.indexOf("type:'end'");
            var msg = "";
            if (num == -1) {
                msg += "请设置开始节点!" + "\n";
            }
            if (endNum == -1) {
                msg += "请设置结束节点!" + "\n";
            }
            if (msg != "") {
                result.success = false;
                result.msg = msg;
                return result;
            }

            return result;
        },
        loadNodes: function() {
            // 流程数据的加载
            if (this.config.restore) {
                var restore = this.config.restore;
                //已存在矩形数据集合，临时变量，便于路径连线处理
                var rectArrayTemp = {};
                // 矩形数据加载
                if (restore.states) {
                    for (var rectId in restore.states) {
                        var rect = new arkflow.FlowNode($.extend(true, {},
                            arkflow.config.tools.states[restore.states[rectId].type],
                            restore.states[rectId]), this.paper);
                        //添加矩形数据到流程图显示
                        rect.restore(restore.states[rectId]);
                        //矩形数据临时集合
                        rectArrayTemp[rectId] = rect;
                        //本流程图中矩形数据集合
                        this.rectArray[rect.getId()] = rect;
                    }
                }
                //路径数据加载
                if (restore.paths) {
                    for (var pathId in restore.paths) {
                        var path = new arkflow.Path($.extend(true, {}, arkflow.config.tools.path,
                            restore.paths[pathId]), this.paper, rectArrayTemp[restore.paths[pathId].from],
                            rectArrayTemp[restore.paths[pathId].to]);
                        //添加路径数据到流程图显示
                        path.restore(restore.paths[pathId]);
                        //本流程图中路径数据集合
                        this.pathArray[path.getId()] = path;
                    }
                }
            }

        },
        loadHistoryAndActiveNodes: function() {
            //历史流程节点
            var hiRects = arkflow.config.historyRects;
            //当前活动节点
            var acRects = arkflow.config.activeRects;
            if (hiRects.rects.length || acRects.rects.length) {
                //流程数据
                var flowData = {};
                for (var pathId in this.pathArray) {
                    if (!flowData[this.pathArray[pathId].from().text()]) {
                        flowData[this.pathArray[pathId].from().text()] = {
                            rect : this.pathArray[pathId].from(),
                            paths : {}
                        };
                    }
                    flowData[this.pathArray[pathId].from().text()].paths[this.pathArray[pathId].text()] = this.pathArray[pathId];
                    if (!flowData[this.pathArray[pathId].to().text()]) {
                        flowData[this.pathArray[pathId].to().text()] = {
                            rect : this.pathArray[pathId].to(),
                            paths : {}
                        };
                    }
                }
                //历史流程数据解析封装
                for (var i = 0; i < hiRects.rects.length; i++) {
                    if (flowData[hiRects.rects[i].name]) {
                        flowData[hiRects.rects[i].name].rect.attr(hiRects.rectAttr);
                    }
                    for (var j = 0; j < hiRects.rects[i].paths.length;j++) {
                        if (flowData[hiRects.rects[i].name].paths[hiRects.rects[i].paths[j]]) {
                            flowData[hiRects.rects[i].name].paths[hiRects.rects[i].paths[j]]
                                .attr(hiRects.pathAttr);
                        }
                    }
                }

                //当前活动流程数据解析封装
                for (var i = 0; i < acRects.rects.length; i++) {
                    if (flowData[acRects.rects[i].name]) {
                        flowData[acRects.rects[i].name].rect.attr(acRects.rectAttr);
                    }
                    for (var j = 0; j < acRects.rects[i].paths.length; j++) {
                        if (flowData[acRects.rects[i].name].paths[acRects.rects[i].paths[j]]) {
                            flowData[acRects.rects[i].name].paths[acRects.rects[i].paths[j]]
                                .attr(acRects.pathAttr);
                        }
                    }
                }
            }
        }
    }, {
        flowMap: {},
        register: function(flowId, flow) {
            arkflow.ArkFlow[flowId] = flow;
        },
        findFlow: function(flowId) {
            return arkflow.ArkFlow[flowId];
        }
    });

    //obj：arkflow对象
    //页面元素：如<div id='arkflow'></div>
    $.fn.arkflow = function(obj) {
        return this.each(function() {
            new arkflow.ArkFlow(this, obj);
        });
    };

})(jQuery);
